package com.boge.activiti;

import org.activiti.engine.*;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.junit.jupiter.api.Test;

import java.util.List;

public class Activiti7Test01 {

    /**
     * 获取ProcessEngine对象的第一种方式
     */
    @Test
    public void test1(){
        // 通过 getDefaultProcessEngine()方法获取流程引擎对象 会加载resources 目录下的 activit.cfg.xml
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        System.out.println(processEngine);
    }

    /**
     * 基于Java代码获取ProcessEngine对象
     * Eclipse
     * IDEA
     * Activiti6官方提供的流程设计器
     */
    @Test
    public void test2(){
        ProcessEngine processEngine = ProcessEngineConfiguration
                .createStandaloneProcessEngineConfiguration()
                .setJdbcDriver("com.mysql.cj.jdbc.Driver")
                .setJdbcUrl("jdbc:mysql://localhost:3306/activiti7?nullCatalogMeansCurrent=true")
                .setJdbcUsername("root")
                .setJdbcPassword("root")
                .setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE) // 设置自动维护表结构
                .buildProcessEngine();
        System.out.println("processEngine = " + processEngine);
    }


    /**
     * 一、流程部署操作
     * act_re_deployment（部署信息表）会新增一条部署记录 act_re_procdef（流程定义表）会新增流程定义记录
     * act_ge_bytearray（资源文件表）会存储bpmn文件内容
     */
    @Test
    public void processDeployment(){
        // 1.获取ProcessEngine对象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        // 2.完成流程的部署操作 需要通过RepositoryService来完成
        RepositoryService repositoryService = processEngine.getRepositoryService();
        // 3.完成部署操作
        Deployment deploy = repositoryService.createDeployment()
                .addClasspathResource("flow/test1.bpmn20.xml")
                .name("第一个流程")
                .deploy(); // 是一个流程部署的行为 可以部署多个流程定义的
        System.out.println(deploy.getId());
        System.out.println(deploy.getName());
    }


    /**
     * 二、查询当前部署的流程有哪些
     */
    @Test
    public void QueryDeployedProcessList() {
        ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
        RepositoryService repositoryService = engine.getRepositoryService();
        // 查询有哪些部署的流程--》查询相关的流程定义信息
        // repositoryService.createDeploymentQuery() 查询流程部署的相关信息
        // repositoryService.createProcessDefinitionQuery() 查询部署的流程的相关的定义
        List<Deployment> list = repositoryService.createDeploymentQuery().list(); // 查询所有的部署信息
        for (Deployment deployment : list) {
            System.out.println(deployment.getId());
            System.out.println(deployment.getName());
        }

        List<ProcessDefinition> list1 = repositoryService.createProcessDefinitionQuery().list();
        for (ProcessDefinition processDefinition : list1) {
            System.out.println(processDefinition.getId());
            System.out.println(processDefinition.getName());
            System.out.println(processDefinition.getDescription());
        }
    }



    /**
     * 三、部署流程删除操作
     * 删除已部署的流程定义及其相关资源
     */
    @Test
    public void deploymentProcessDelete() {
        // 1.获取流程引擎实例
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

        // 2.获取仓库服务(用于管理流程部署)
        RepositoryService repositoryService = processEngine.getRepositoryService();

        try {
            // 3.设置要删除的部署ID（这里应该替换为实际要删除的部署ID）
            String deploymentId = "2501"; // 示例部署ID

            // 4.执行删除操作（false表示不级联删除运行中的流程实例）
            // repositoryService.deleteDeployment(deploymentId);

            // 或者使用级联删除（true表示同时删除运行中的流程实例和历史数据）
            repositoryService.deleteDeployment(deploymentId, true);

            System.out.println("流程部署删除成功，部署ID：" + deploymentId);

        } catch (ActivitiObjectNotFoundException e) {
            System.err.println("删除失败：未找到指定的流程部署");
            e.printStackTrace();
        } catch (ActivitiException e) {
            System.err.println("删除流程部署时发生错误");
            e.printStackTrace();
        }
    }


    /**
     * 开启一个流程
     */
    @Test
    public void StartOneProcess(){
        ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
        // 发起流程 需要通过 runtimeService来实现
        RuntimeService runtimeService = engine.getRuntimeService();
        // 通过流程定义ID来启动流程  返回的是流程实例对象
        ProcessInstance processInstance = runtimeService
                .startProcessInstanceById("test1:1:3");
        System.out.println("processInstance.getId() = " + processInstance.getId());
        System.out.println("processInstance.getDeploymentId() = " + processInstance.getDeploymentId());
        System.out.println("processInstance.getDescription() = " + processInstance.getDescription());
    }

    /**
     * 待办查询
     */
    @Test
    public void test6(){
        ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
        // 待办查询 执行中的任务处理通过 TaskService来实现
        TaskService taskService = engine.getTaskService();
        // Task 对象对应的其实就是 act_ru_task 这张表的记录
        List<Task> list = taskService.createTaskQuery().taskAssignee("lisi").list();
        if(list != null && list.size() > 0){
            for (Task task : list) {
                System.out.println(task.getId());
                System.out.println(task.getName());
                System.out.println(task.getAssignee());
            }
        }else{
            System.out.println("当前没有待办任务");
        }
    }

    /**
     * 任务审批
     */
    @Test
    public void test7(){
        ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
        // 做任务申请 也需要通过 TaskService 来实现
        TaskService taskService = engine.getTaskService();
        // 根据当前登录用户查询出对应的待办信息
        List<Task> list = taskService.createTaskQuery().taskAssignee("lisi").list();
        if(list != null && list.size() > 0){
            for (Task task : list) {
                // 做对应的任务审批处理
                taskService.complete(task.getId());
            }
        }
        // 完成任务
        // taskService.complete("2505");
    }
}
